home *** CD-ROM | disk | FTP | other *** search
/ Internet Info 1994 March / Internet Info CD-ROM (Walnut Creek) (March 1994).iso / networking / ip / ka9q / aztecnos.arc / NRCMD.C < prev    next >
Encoding:
C/C++ Source or Header  |  1989-02-16  |  13.3 KB  |  609 lines

  1. /* net/rom user command processing
  2.  * Dan Frank, W9NK
  3.  */
  4.  
  5. #include <stdio.h>
  6. #include "global.h"
  7. #include "mbuf.h"
  8. #include "ax25.h"
  9. #include "netrom.h"
  10. #include "timer.h"
  11. #include "iface.h"
  12. #include "lapb.h"
  13. #include "cmdparse.h"
  14. #include <ctype.h>
  15.  
  16. extern struct iface *Ifaces ;
  17. static int donfdump(),doobsotick(),donodetick(),
  18.     dointerface(), dobcnodes(), donodetimer(), donrroute(),
  19.     doobsotimer(), donodefilter(), donrverbose() ;
  20.  
  21. static struct cmds Nrcmds[] = {
  22.     "bcnodes",    dobcnodes,    0, 2,    "netrom bcnodes <interface>",
  23.     "interface",    dointerface,    0, 4,
  24.         "netrom interface <interface> <alias> <quality>",
  25.     "nodefilter",    donodefilter,    0, 0,    NULLCHAR,
  26.     "nodetimer",    donodetimer,    0, 0,    NULLCHAR,
  27.     "obsotimer",    doobsotimer,    0, 0,    NULLCHAR,
  28.     "route",    donrroute,    0, 0,    NULLCHAR,
  29.     "verbose",    donrverbose,0, 0,    NULLCHAR,
  30.     NULLCHAR,    NULLFP,        0, 0,
  31.         "netrom subcommands: bcnodes interface nodetimer nodefilter obsotimer route verbose",
  32. } ;
  33.  
  34. static struct timer Nodetimer ;    /* timer for nodes broadcasts */
  35. static struct timer Obsotimer ;    /* timer for aging routes */
  36.  
  37. /* Command multiplexer */
  38. donetrom(argc,argv)
  39. int argc ;
  40. char *argv[] ;
  41. {
  42.     return subcmd(Nrcmds,argc,argv) ;
  43. }
  44.  
  45. static int dorouteadd(), doroutedrop(), doroutedump(), dorouteinfo() ;
  46.  
  47. static struct cmds Routecmds[] = {
  48.     "add",    dorouteadd,    0, 6,
  49.         "netrom route add <alias> <destination> <interface> <quality> <neighbor>",
  50.     "drop",    doroutedrop, 0, 4,
  51.         "netrom route drop <destination> <neighbor> <interface>",
  52.     "info", dorouteinfo, 0, 2,
  53.         "netrom route info <destination>",
  54.     NULLCHAR,    NULLFP,    0, 0,
  55.         "netrom route subcommands: add drop info",
  56. } ;
  57.  
  58. /* Route command multiplexer */
  59. static
  60. donrroute(argc, argv)
  61. int argc ;
  62. char *argv[] ;
  63. {
  64.     if (argc < 2) {
  65.         doroutedump() ;
  66.         return 0 ;
  67.     }
  68.     return subcmd(Routecmds,argc,argv) ;
  69. }
  70.  
  71. /* Dump a list of known routes */
  72. static
  73. doroutedump()
  74. {
  75.     register struct nrroute_tab *rp ;
  76.     register int i, column ;
  77.     char buf[16] ;
  78.     char *cp ;
  79.     
  80.     column = 1 ;
  81.     
  82.     for (i = 0 ; i < NRNUMCHAINS ; i++)
  83.         for (rp = Nrroute_tab[i] ; rp != NULLNRRTAB ; rp = rp->next) {
  84.             strcpy(buf,rp->alias) ;
  85.             /* remove trailing spaces */
  86.             if ((cp = strchr(buf,' ')) == NULLCHAR)
  87.                 cp = &buf[strlen(buf)] ;
  88.             if (cp != buf)        /* don't include colon for null alias */
  89.                 *cp++ = ':' ;
  90.             pax25(cp,&rp->call) ;
  91.             printf("%-16s  ",buf) ;
  92.             if (column++ == 4) {
  93.                 printf("\n") ;
  94.                 column = 1 ;
  95.             }
  96.         }
  97.  
  98.     if (column != 1)
  99.         printf("\n") ;
  100.         
  101.     return 0 ;
  102. }
  103.  
  104. /* print detailed information on an individual route */
  105. static int
  106. dorouteinfo(argc,argv)
  107. int argc ;
  108. char *argv[] ;
  109. {
  110.     register struct nrroute_tab *rp ;
  111.     register struct nr_bind *bp ;
  112.     register struct nrnbr_tab *np ;
  113.     struct ax25_addr dest ;
  114.     char neighbor[60] ;
  115.  
  116.     if (setcall(&dest,argv[1]) == -1) {
  117.         printf ("bad destination name\n") ;
  118.         return -1 ;
  119.     }
  120.         
  121.     if ((rp = find_nrroute(&dest)) == NULLNRRTAB) {
  122.         printf("no such route\n") ;
  123.         return -1 ;
  124.     }
  125.  
  126.     for (bp = rp->routes ; bp != NULLNRBIND ; bp = bp->next) {
  127.         np = bp->via ;
  128.         psax25(neighbor,np->call) ;
  129.         printf("%1s %3d  %3d  %-8s  %s\n",
  130.                 (bp->flags & NRB_PERMANENT ? "P" :
  131.                  bp->flags & NRB_RECORDED ? "R" : " "),
  132.                 bp->quality,bp->obsocnt,
  133.                 Nrifaces[np->iface].iface->name,
  134.                 neighbor) ;
  135.     }
  136.     return 0 ;
  137. }
  138.         
  139. /* convert a null-terminated alias name to a blank-filled, upcased */
  140. /* version.  Return -1 on failure. */
  141. static int
  142. putalias(to,from)
  143. register char *to, *from ;
  144. {
  145.     int len, i ;
  146.     
  147.     if ((len = strlen(from)) > ALEN) {
  148.         printf ("alias too long - six characters max\n") ;
  149.         return -1 ;
  150.     }
  151.     
  152.     for (i = 0 ; i < ALEN ; i++) {
  153.         if (i < len) {
  154.             if (islower(*from))
  155.                 *to++ = toupper(*from++) ;
  156.             else
  157.                 *to++ = *from++ ;
  158.         }
  159.         else
  160.             *to++ = ' ' ;
  161.     }
  162.             
  163.     *to = '\0' ;
  164.     return 0 ;
  165. }
  166.  
  167. /* Add a route */
  168. static int
  169. dorouteadd(argc, argv)
  170. int argc ;
  171. char *argv[] ;
  172. {
  173.     char alias[7] ;
  174.     struct ax25_addr dest ;
  175.     unsigned quality ;
  176.     char neighbor[AXALEN * 3] ;
  177.     register int i ;
  178.     int naddr ;
  179.  
  180.     /* format alias (putalias prints error message if necessary) */
  181.     if (putalias(alias,argv[1]) == -1)
  182.         return -1 ;
  183.  
  184.     /* format destination callsign */
  185.     if (setcall(&dest,argv[2]) == -1) {
  186.         printf("bad destination callsign\n") ;
  187.         return -1 ;
  188.     }
  189.  
  190.     /* find interface */
  191.     for (i = 0 ; i < Nr_numiface ; i++)
  192.         if (!strcmp(Nrifaces[i].iface->name,argv[3]))
  193.             break ;
  194.     if (i == Nr_numiface) {
  195.         printf("Interface \"%s\" not found\n",argv[3]) ;
  196.         return -1 ;
  197.     }
  198.     
  199.     /* get and check quality value */
  200.     if ((quality = atoi(argv[4])) > 255) {
  201.         printf("maximum route quality is 255\n") ;
  202.         return -1 ;
  203.     }
  204.  
  205.     /* Change from 871225 -- no digis in net/rom table */
  206.     naddr = argc - 5 ;
  207.     if (naddr > 1) {
  208.         printf("Use the ax25 route command to specify digipeaters\n") ;
  209.         return -1 ;
  210.     }
  211.     
  212.     /* format neighbor address string */
  213.     setpath(neighbor,&argv[5],naddr) ;
  214.  
  215.     return nr_routeadd(alias,&dest,i,quality,neighbor,1,0) ;
  216. }
  217.  
  218.  
  219. /* drop a route */
  220. static int
  221. doroutedrop(argc,argv)
  222. int argc ;
  223. char *argv[] ;
  224. {
  225.     struct ax25_addr dest, neighbor ;
  226.     register int i ;
  227.  
  228.     /* format destination and neighbor callsigns */
  229.     if (setcall(&dest,argv[1]) == -1) {
  230.         printf("bad destination callsign\n") ;
  231.         return -1 ;
  232.     }
  233.     if (setcall(&neighbor,argv[2]) == -1) {
  234.         printf("bad neighbor callsign\n") ;
  235.         return -1 ;
  236.     }
  237.  
  238.     /* find interface */
  239.     for (i = 0 ; i < Nr_numiface ; i++)
  240.         if (!strcmp(Nrifaces[i].iface->name,argv[3]))
  241.             break ;
  242.     if (i == Nr_numiface) {
  243.         printf("Interface \"%s\" not found\n",argv[3]) ;
  244.         return -1 ;
  245.     }
  246.  
  247.     return nr_routedrop(&dest,&neighbor,i) ;
  248. }
  249.     
  250.     
  251. /* make an interface available to net/rom */
  252. static int
  253. dointerface(argc,argv)
  254. int argc ;
  255. char *argv[] ;
  256. {
  257.     int i;
  258.     register struct iface *ifp ;
  259.  
  260.     if (Nr_iface == NULLIF) {
  261.         printf("Attach netrom interface first\n") ;
  262.         return 1 ;
  263.     }
  264.     
  265.     if (Nr_numiface >= NRNUMIFACE) {
  266.         printf("Only %d net/rom interfaces available\n",NRNUMIFACE) ;
  267.         return 1 ;
  268.     }
  269.     
  270.     for(ifp=Ifaces;ifp != NULLIF;ifp = ifp->next){
  271.         if(strcmp(argv[1],ifp->name) == 0)
  272.             break;
  273.     }
  274.     if(ifp == NULLIF){
  275.         printf("Interface \"%s\" unknown\n",argv[1]);
  276.         return 1;
  277.     }
  278.     for (i = 0 ; i < Nr_numiface ; i++)
  279.         if (Nrifaces[i].iface == ifp) {
  280.             printf("Interface \"%s\" is already registered\n",argv[1]) ;
  281.             return 1 ;
  282.         }
  283.         
  284.     Nrifaces[Nr_numiface].iface = ifp ;
  285.  
  286.     if (putalias(Nrifaces[Nr_numiface].alias,argv[2]) == -1)
  287.         return 1 ;
  288.         
  289.     if ((Nrifaces[Nr_numiface].quality = atoi(argv[3])) > 255) {
  290.         printf("Quality cannot be greater than 255\n") ;
  291.         return 1 ;
  292.     }
  293.         
  294.     Nr_numiface++ ;            /* accept this interface */
  295.     return 0 ;
  296. }
  297.  
  298. /* Broadcast nodes list on named interface. */
  299. static int
  300. dobcnodes(argc,argv)
  301. int argc ;
  302. char *argv[] ;
  303. {
  304.     register int i ;
  305.  
  306.     for (i = 0 ; i < Nr_numiface ; i++)
  307.         if (!strcmp(Nrifaces[i].iface->name,argv[1]))
  308.             break ;
  309.     if (i == Nr_numiface) {
  310.         printf("Interface \"%s\" not found\n",argv[1]) ;
  311.         return 1 ;
  312.     }
  313.         
  314.     nr_bcnodes(i) ;
  315. }
  316.  
  317. #define TICKSPERSEC    (1000L / MSPTICK)    /* Ticks per second */
  318.  
  319. /* Set outbound node broadcast interval */
  320. static int
  321. donodetimer(argc,argv)
  322. int argc;
  323. char *argv[];
  324. {
  325.     if(argc < 2){
  326.         printf("%lu/%lu\n",(Nodetimer.start - Nodetimer.count)/TICKSPERSEC,
  327.         Nodetimer.start/TICKSPERSEC);
  328.         return 0;
  329.     }
  330.     stop_timer(&Nodetimer) ;    /* in case it's already running */
  331.     Nodetimer.func = (void (*)())donodetick;/* what to call on timeout */
  332.     Nodetimer.arg = NULLCHAR;        /* dummy value */
  333.     Nodetimer.start = atoi(argv[1])*TICKSPERSEC;    /* set timer duration */
  334.     start_timer(&Nodetimer);        /* and fire it up */
  335.     return 0;
  336. }
  337.  
  338. static int
  339. donodetick()
  340. {
  341.     register int i ;
  342.  
  343.     for (i = 0 ; i < Nr_numiface ; i++)
  344.         nr_bcnodes(i) ;
  345.  
  346.     /* Restart timer */
  347.     start_timer(&Nodetimer) ;
  348. }
  349.  
  350. /* Set timer for aging routes */
  351. static int
  352. doobsotimer(argc,argv)
  353. int argc;
  354. char *argv[];
  355. {
  356.     if(argc < 2){
  357.         printf("%lu/%lu\n",(Obsotimer.start - Obsotimer.count)/TICKSPERSEC,
  358.         Obsotimer.start/TICKSPERSEC);
  359.         return 0;
  360.     }
  361.     stop_timer(&Obsotimer) ;    /* just in case it's already running */
  362.     Obsotimer.func = (void (*)())doobsotick;/* what to call on timeout */
  363.     Obsotimer.arg = NULLCHAR;        /* dummy value */
  364.     Obsotimer.start = atoi(argv[1])*TICKSPERSEC;    /* set timer duration */
  365.     start_timer(&Obsotimer);        /* and fire it up */
  366.     return 0;
  367. }
  368.  
  369.  
  370. /* Go through the routing table, reducing the obsolescence count of
  371.  * non-permanent routes, and purging them if the count reaches 0
  372.  */
  373. static int
  374. doobsotick()
  375. {
  376.     register struct nrnbr_tab *np ;
  377.     register struct nrroute_tab *rp, *rpnext ;
  378.     register struct nr_bind *bp, *bpnext ;
  379.     struct ax25_addr neighbor ;
  380.     int i ;
  381.  
  382.     for (i = 0 ; i < NRNUMCHAINS ; i++) {
  383.         for (rp = Nrroute_tab[i] ; rp != NULLNRRTAB ; rp = rpnext) {
  384.             rpnext = rp->next ;     /* save in case we free this route */
  385.             for (bp = rp->routes ; bp != NULLNRBIND ; bp = bpnext) {
  386.                 bpnext = bp->next ;    /* in case we free this binding */
  387.                 if (bp->flags & NRB_PERMANENT)    /* don't age these */
  388.                     continue ;
  389.                 if (--bp->obsocnt == 0) {        /* time's up! */
  390.                     if (bp->next != NULLNRBIND)
  391.                         bp->next->prev = bp->prev ;
  392.                     if (bp->prev != NULLNRBIND)
  393.                         bp->prev->next = bp->next ;
  394.                     else
  395.                         rp->routes = bp->next ;
  396.                     rp->num_routes-- ;            /* one less binding */
  397.                     np = bp->via ;                /* find the neighbor */
  398.                     free(bp) ;                    /* now we can free the bind */
  399.                     /* Check to see if we can free the neighbor */
  400.                     if (--np->refcnt == 0) {
  401.                         if (np->next != NULLNTAB)
  402.                             np->next->prev = np->prev ;
  403.                         if (np->prev != NULLNTAB)
  404.                             np->prev->next = np->next ;
  405.                         else {
  406.                             memcpy(neighbor.call,np->call,ALEN) ;
  407.                             neighbor.ssid = np->call[ALEN] ;
  408.                             Nrnbr_tab[nrhash(&neighbor)] = np->next ;
  409.                         }
  410.                         free(np) ;    /* free the storage */
  411.                     }
  412.                 }
  413.             }
  414.             if (rp->num_routes == 0) {        /* did we free them all? */
  415.                 if (rp->next != NULLNRRTAB)
  416.                     rp->next->prev = rp->prev ;
  417.                 if (rp->prev != NULLNRRTAB)
  418.                     rp->prev->next = rp->next ;
  419.                 else
  420.                     Nrroute_tab[i] = rp->next ;
  421.  
  422.                 free(rp) ;
  423.             }
  424.         }
  425.     }
  426.  
  427.     start_timer(&Obsotimer) ;
  428. }
  429.  
  430.  
  431. static int donfadd(), donfdrop(), donfmode() ;
  432.  
  433. static struct cmds Nfcmds[] = {
  434.     "add",    donfadd,    0, 3,
  435.         "netrom nodefilter add <neighbor> <interface>",
  436.     "drop",    donfdrop,    0, 3,
  437.         "netrom nodefilter drop <neighbor> <interface>",
  438.     "mode",    donfmode,    0, 0,    NULLCHAR,
  439.     NULLCHAR,    NULLFP,    0, 0,
  440.         "nodefilter subcommands: add drop mode",
  441. } ;
  442.  
  443. /* nodefilter command multiplexer */
  444. static int
  445. donodefilter(argc,argv)
  446. int argc ;
  447. char *argv[] ;
  448. {
  449.     if (argc < 2) {
  450.         donfdump() ;
  451.         return 0 ;
  452.     }
  453.     return subcmd(Nfcmds,argc,argv) ;
  454. }
  455.  
  456. /* display a list of <callsign,interface> pairs from the filter
  457.  * list.
  458.  */
  459. static int
  460. donfdump()
  461. {
  462.     int i, column = 1 ;
  463.     struct nrnf_tab *fp ;
  464.     char buf[16] ;
  465.  
  466.     for (i = 0 ; i < NRNUMCHAINS ; i++)
  467.         for (fp = Nrnf_tab[i] ; fp != NULLNRNFTAB ; fp = fp->next) {
  468.             pax25(buf,&fp->neighbor) ;
  469.             printf("%-7s %-8s  ",
  470.                     buf,Nrifaces[fp->iface].iface->name) ;
  471.             if (column++ == 4) {
  472.                 printf("\n") ;
  473.                 column = 1 ;
  474.             }
  475.         }
  476.  
  477.     if (column != 1)
  478.         printf("\n") ;
  479.  
  480.     return 0 ;
  481. }
  482.  
  483. /* add an entry to the filter table */
  484. static int
  485. donfadd(argc,argv)
  486. int argc ;
  487. char *argv[] ;
  488. {
  489.     struct ax25_addr neighbor ;
  490.     register int i ;
  491.  
  492.     /* format callsign */
  493.     if (setcall(&neighbor,argv[1]) == -1) {
  494.         printf("bad neighbor callsign\n") ;
  495.         return -1 ;
  496.     }
  497.  
  498.     /* find interface */
  499.     for (i = 0 ; i < Nr_numiface ; i++)
  500.         if (!strcmp(Nrifaces[i].iface->name,argv[2]))
  501.             break ;
  502.     if (i == Nr_numiface) {
  503.         printf("Interface \"%s\" not found\n",argv[2]) ;
  504.         return -1 ;
  505.     }
  506.  
  507.     return nr_nfadd(&neighbor,i) ;
  508. }
  509.  
  510. /* drop an entry from the filter table */
  511. static int
  512. donfdrop(argc,argv)
  513. int argc ;
  514. char *argv[] ;
  515. {
  516.     struct ax25_addr neighbor ;
  517.     register int i ;
  518.  
  519.     /* format neighbor callsign */
  520.     if (setcall(&neighbor,argv[1]) == -1) {
  521.         printf("bad neighbor callsign\n") ;
  522.         return -1 ;
  523.     }
  524.  
  525.     /* find interface */
  526.     for (i = 0 ; i < Nr_numiface ; i++)
  527.         if (!strcmp(Nrifaces[i].iface->name,argv[2]))
  528.             break ;
  529.     if (i == Nr_numiface) {
  530.         printf("Interface \"%s\" not found\n",argv[2]) ;
  531.         return -1 ;
  532.     }
  533.  
  534.     return nr_nfdrop(&neighbor,i) ;
  535. }
  536.  
  537. /* nodefilter mode subcommand */
  538. static int
  539. donfmode(argc,argv)
  540. int argc ;
  541. char *argv[] ;
  542. {
  543.     if (argc < 2) {
  544.         printf("filter mode is ") ;
  545.         switch (Nr_nfmode) {
  546.             case NRNF_NOFILTER:
  547.                 printf("none\n") ;
  548.                 break ;
  549.             case NRNF_ACCEPT:
  550.                 printf("accept\n") ;
  551.                 break ;
  552.             case NRNF_REJECT:
  553.                 printf("reject\n") ;
  554.                 break ;
  555.             default:
  556.                 printf("some strange, unknown value\n") ;
  557.         }
  558.         return 0 ;
  559.     }
  560.     
  561.     switch (argv[1][0]) {
  562.         case 'n':
  563.         case 'N':
  564.             Nr_nfmode = NRNF_NOFILTER ;
  565.             break ;
  566.         case 'a':
  567.         case 'A':
  568.             Nr_nfmode = NRNF_ACCEPT ;
  569.             break ;
  570.         case 'r':
  571.         case 'R':
  572.             Nr_nfmode = NRNF_REJECT ;
  573.             break ;
  574.         default:
  575.             printf("modes are: none accept reject\n") ;
  576.             return -1 ;
  577.     }
  578.  
  579.     return 0 ;
  580. }
  581.  
  582. /* verbose route broadcast */
  583. static int
  584. donrverbose(argc,argv)
  585. int argc ;
  586. char *argv[] ;
  587. {
  588.     if (argc < 2) {
  589.         printf("verbose is %s\n", Nr_verbose ? "yes" : "no" ) ;
  590.         return 0 ;
  591.     }
  592.     
  593.     switch (argv[1][0]) {
  594.         case 'n':
  595.         case 'N':
  596.             Nr_verbose = 0 ;
  597.             break ;
  598.         case 'y':
  599.         case 'Y':
  600.             Nr_verbose = 1 ;
  601.             break ;
  602.         default:
  603.             printf("use: netrom verbose [yes|no]\n") ;
  604.             return -1 ;
  605.     }
  606.  
  607.     return 0 ;
  608. }
  609.